package server.gameplay;

import java.awt.Point;
import java.util.List;

public class Tower implements Buildings {

	private static final int TOWER_RANGE = 100;
	private int buildLevel;
	private long timer = System.currentTimeMillis();
	private long reduceTime;

	public Tower(int level) {
		setBuildLevel(level);
		reduceTime = System.currentTimeMillis();
	}

	// no population growth.
	public float growth(float curRes) {
		return 0;
	}

	public int getBuildLevel() {
		return buildLevel;
	}

	public void setBuildLevel(int buildLevel) {
		this.buildLevel = buildLevel;
	}

	// Building defense is high in towers
	public float defend(int attackMorale, int ownMorale, int attackArmory) {
		// some formula to reduce number of residents.
		float reduce = (((float) (attackMorale - ownMorale)) / 5f)
				+ ((float) (attackArmory - (buildLevel * 2.5)) / 4f);
		if (reduce < 0) {
			reduce = Math.abs(1 / (reduce - 1));
		} else {
			reduce++;
		}
		return reduce;
	}

	public boolean isUpgradeable(float res) {
		return (buildLevel < 3) && (res >= upgradeCost());
	}

	public Tower clone() {
		return new Tower(buildLevel);
	}

	public Tower clone(int level) {
		return new Tower(level);
	}

	public int upgradeCost() {
		return 20;
	}

	public void addLevel() {
		buildLevel++;
	}

	public int getLevel() {
		return buildLevel;
	}

	/**
	 * Units in the vicinity can be attacked by tower, if the least minimum time
	 * has expired. If attacked, unit is set to null (and no reference to that
	 * unit should exist) and timer resets.
	 */

	private Unit attackTarget;

	public void InRange(Point pos, List<Unit> units, ServerPlayerPackage owner) {
		if (System.currentTimeMillis() - timer > (2000 / (buildLevel + 2))) {

			if (attackTarget != null && units.remove(attackTarget)) {
				attackTarget = null;
			}

			for (int i = 0; i < units.size(); i++) {
				Unit u = units.get(i);

				// least time between attacks, adjustments needed?
				// lvl 0 1000ms
				// lvl 1 666ms
				// lvl 2 500ms
				// lvl 3 400ms
				// distance set to 200 pixels at width and 100 at height.

				if (!owner.equals(u.getOwner())
						&& u.getPosition().distance(pos) < TOWER_RANGE
								+ Math.abs(TOWER_RANGE
										* Math.cos(Math.atan2(u.getPosition().y
												- pos.y, u.getPosition().x
												- pos.x)))) {
					attackTarget = u;
					timer = System.currentTimeMillis();
					return;
				}
			}
		}
	}

	public void reduceLevel() {
		if (System.currentTimeMillis() - reduceTime > 100 && buildLevel > 0) {
			buildLevel--;
			reduceTime = System.currentTimeMillis();
		}
	}
}
